home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 220 / 220.xpi / chrome / flashgot.jar / content / flashgot / FlashGot.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2010-01-24  |  38.1 KB  |  1,760 lines

  1. /***** BEGIN LICENSE BLOCK *****
  2.     FlashGot - a Firefox extension for external download managers integration
  3.     Copyright (C) 2004-2007 Giorgio Maone - g.maone@informaction.com
  4.     
  5.     contributors:
  6.     Max Velasques (wxDownload Fast support)
  7.     Zhang Ji (BitComet support)
  8.     YuanHongYe (new Thunder support)
  9.  
  10.     
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License as published by
  13.     the Free Software Foundation; either version 2 of the License, or
  14.     (at your option) any later version.
  15.  
  16.     This program is distributed in the hope that it will be useful,
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.     GNU General Public License for more details.
  20.  
  21.     You should have received a copy of the GNU General Public License
  22.     along with this program; if not, write to the Free Software
  23.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  
  25. ***** END LICENSE BLOCK *****/
  26.  
  27. #include "FlashGot.h"
  28.  
  29. FGCOMGuard *FGCOMGuard::instance = NULL;
  30. int FGCOMGuard::refCount = 0;
  31.  
  32.  
  33. #define BUF_SIZE 8192
  34.  
  35. char g_buf[BUF_SIZE];
  36. wchar_t g_wbuf[BUF_SIZE];
  37.  
  38.  
  39.  
  40. extern void fail(char *msg, int code) 
  41. {
  42.     MessageBox(NULL, msg,
  43.                       "FlashGot Error",
  44.                       MB_OK | MB_ICONERROR);
  45.     exit(code);
  46. }
  47.  
  48.  
  49. using namespace std;
  50.  
  51.  
  52.  
  53.  
  54.  
  55. class DMSAddUrlFamily :
  56.     public DMSupportCOM
  57. {
  58.     void dispatch(const DownloadInfo *downloadInfo)
  59.     {
  60.         CookieManager cm(downloadInfo);
  61.         HELPER(h);
  62.         int linksCount=downloadInfo->linksCount;
  63.         if(linksCount>0)
  64.         {
  65.             if(linksCount<2) {
  66.                 LinkInfo link=downloadInfo->links[0];
  67.                 VARIANT v[3];
  68.                 v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  69.                 v[2].bstrVal=link.url;
  70.                 v[1].bstrVal=link.comment;
  71.                 v[0].bstrVal=downloadInfo->referer;
  72.                 h.invoke("AddUrl", v, 3);
  73.             } 
  74.             else 
  75.             {
  76.                 FGArray fgArray(downloadInfo);
  77.                 h.invoke("AddUrlList", fgArray.asVariant(), 1);
  78.             }
  79.         }
  80.     }
  81. };
  82.  
  83.  
  84.  
  85.  
  86. class DMSFlashGet :
  87.     public DMSAddUrlFamily
  88. {
  89.  
  90. protected:
  91.     
  92.     const char * getProgId() { return "JetCar.Netscape"; }
  93.     
  94. public:
  95.     
  96.     const char * getName() { return "FlashGet"; }
  97.  
  98. };
  99.  
  100. class DMSFlashGet2 :
  101.     public DMSAddUrlFamily
  102. {
  103.  
  104. protected:
  105.     
  106.     const char * getProgId() { return "FG2CatchUrl.Netscape"; }
  107.     
  108. public:
  109.     
  110.     const char * getName() { return "FlashGet 2"; }
  111.  
  112. };
  113.  
  114.  
  115. class DMSFlashGet2X :
  116.     public DMSupportCOM
  117. {
  118.  
  119. protected:
  120.     
  121.     const char * getProgId() { return "BHO.IFlashGetNetscapeEx"; }
  122.     
  123. public:
  124.     
  125.     const char * getName() { return "FlashGet 2.x"; }
  126.     
  127.     void dispatch(const DownloadInfo *downloadInfo)
  128.     {
  129.         CookieManager cm(downloadInfo);
  130.         HELPER(h);
  131.         int linksCount=downloadInfo->linksCount;
  132.         if(linksCount>0) try
  133.         {
  134.             
  135.             if(linksCount<2) {
  136.                 LinkInfo link = downloadInfo->links[0];
  137.                 VARIANT v[6];
  138.                 try
  139.                 {
  140.                 
  141.                     v[5].vt = v[4].vt = v[3].vt = v[2].vt = v[1].vt = v[0].vt = VT_BSTR;
  142.                     v[5].bstrVal = link.url;
  143.                     v[4].bstrVal = link.comment.length() > 0 ? link.url : link.comment;
  144.                     v[3].bstrVal = downloadInfo->referer;
  145.                     v[2].bstrVal = SysAllocString(L"FlashGet3");
  146.                     v[1].bstrVal = link.cookie;
  147.                     v[0].bstrVal = SysAllocString(L"0");
  148.                     h.invoke("AddUrlEx", v, 6);
  149.                 } catch(...)
  150.                 {
  151.                     v[2].bstrVal = SysAllocString(L"FlashGet");
  152.                     try
  153.                     {
  154.                         h.invoke("AddUrlEx", v, 6);
  155.                     } catch(...)
  156.                     {
  157.                         VARIANT v[5];
  158.                         v[4].vt = v[3].vt = v[2].vt = v[1].vt = v[0].vt = VT_BSTR;
  159.                         v[4].bstrVal = link.url;
  160.                         v[3].bstrVal = link.comment.length() > 0 ? link.url : link.comment;
  161.                         v[2].bstrVal = downloadInfo->referer;
  162.                         v[1].bstrVal = SysAllocString(L"FlashGet");
  163.                         v[0].bstrVal =  SysAllocString(L"0");
  164.                         h.invoke("AddUrlEx", v, 5);
  165.                     }
  166.                 }
  167.             } 
  168.             else 
  169.             {
  170.                 FGArray fgArray(downloadInfo);
  171.                 VARIANT v[5];
  172.                 try
  173.                 {
  174.                     fgArray.asVariant(&v[4]);
  175.                     v[3].vt = v[2].vt = v[1].vt = v[0].vt = VT_BSTR;
  176.                     v[3].bstrVal = downloadInfo->referer;
  177.                     v[2].bstrVal = SysAllocString(L"FlashGet3");
  178.                     v[1].bstrVal = SysAllocString(L"");
  179.                     v[0].bstrVal = SysAllocString(L"0");
  180.                     h.invoke("AddAll", v, 5);
  181.                     
  182.                 } catch(...)
  183.                 {
  184.                     v[2].bstrVal = SysAllocString(L"FlashGet");
  185.                     v[1].bstrVal = downloadInfo->extras[1]; // document.cookie
  186.                     try
  187.                     {
  188.                         h.invoke("AddAll", v, 5);
  189.                     } catch(...)
  190.                     {
  191.                         VARIANT v[4];
  192.                         
  193.                         fgArray.asVariant(&v[3]);
  194.                         v[2].vt = v[1].vt = v[0].vt = VT_BSTR;
  195.                         v[2].bstrVal = downloadInfo->referer;
  196.                         v[1].bstrVal = SysAllocString(L"FlashGet");
  197.                         v[0].bstrVal = SysAllocString(L"0");
  198.                         
  199.                         h.invoke("AddAll", v, 4);
  200.                     }
  201.             }
  202.             }
  203.         } catch(...)
  204.         {
  205.             LinkInfo link = downloadInfo->links[0];
  206.             char buf[4096];
  207.             sprintf_s(buf, 4096, "%s\n%s\n%s", (char *)link.url, (char *)link.comment, (char *)downloadInfo->referer);
  208.             fail(buf, 1);
  209.         }
  210.     }
  211. };
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219. class DMSFreeDownloadManager :
  220.     public DMSupportCOM
  221. {
  222.  
  223. protected:
  224.  
  225.     const char * getProgId() { return "WG.WGUrlListReceiver"; }
  226.  
  227. public:
  228.     
  229.     const char * getName() { return "Free Download Manager"; }
  230.  
  231.     void dispatch(const DownloadInfo *downloadInfo )
  232.     {
  233.         
  234.         int linksCount=downloadInfo->linksCount;
  235.         if(linksCount>0)
  236.         {
  237.             CookieManager cm(downloadInfo);
  238.             const char *progId;
  239.             char *methodName;
  240.  
  241.             if(linksCount<2)
  242.             {
  243.                 progId="WG.WGUrlReceiver";
  244.                 methodName="AddDownload";
  245.             } else {
  246.                 progId=getProgId();
  247.                 methodName="AddURLToList";
  248.             }
  249.  
  250.             FGCOMHelper fdm(progId);
  251.             fdm.set("Referer",downloadInfo->referer);
  252.             LinkInfo *links=downloadInfo->links;
  253.             for(int j=0; j< linksCount; j++) {
  254.                 LinkInfo l=links[j];
  255.                 fdm.set("Url",l.url);
  256.                 fdm.set("Comment",l.comment);
  257.                 fdm.invoke(methodName);
  258.             }
  259.             if(linksCount>1) fdm.invoke("ShowAddUrlListDialog");
  260.             
  261.         }
  262.     }
  263.     
  264. };
  265.  
  266. class DMSBitComet :
  267.     public DMSupportCOM
  268. {
  269.     protected:
  270.         const char * getProgId() { return "BitCometAgent.BcAgent.1"; }
  271.  
  272.     public:
  273.         const char * getName() { return "BitComet"; }
  274.  
  275.         void dispatch(const DownloadInfo *downloadInfo)
  276.         {
  277.             HELPER(h);
  278.  
  279.             int linksCount = downloadInfo->linksCount;
  280.             if (linksCount > 0)
  281.             {
  282.                 if (linksCount < 2)
  283.                 {
  284.                     VARIANT v[5];
  285.  
  286.                     // write title to param array
  287.                     v[0].vt = VT_NULL;
  288.                     
  289.                     // write ref URL to param array
  290.                     v[1].vt = VT_BSTR;
  291.                     v[1].bstrVal = downloadInfo->referer;
  292.  
  293.                     // write URL title to param array
  294.                     v[2].vt = VT_BSTR;
  295.                     v[2].bstrVal = downloadInfo->links[0].comment;
  296.  
  297.                     // write target URL to param array
  298.                     v[3].vt = VT_BSTR;
  299.                     v[3].bstrVal = downloadInfo->links[0].url;
  300.  
  301.                     // write html content to param array
  302.                     v[4].vt = VT_NULL;
  303.  
  304.                     h.invoke("AddLink", v, 5);
  305.                 }
  306.                 else
  307.                 {
  308.                     VARIANT v[5];
  309.  
  310.                     HRESULT hResult = S_OK;
  311.  
  312.                     SAFEARRAY            *pSA_URL = NULL;
  313.                     SAFEARRAY            *pSA_FLASH = NULL;
  314.                     SAFEARRAYBOUND        bound_url[1];
  315.                     SAFEARRAYBOUND        bound_flash[1];
  316.  
  317.                     bound_url[0].lLbound = 0;
  318.                     bound_url[0].cElements = 2 * linksCount;
  319.  
  320.                     bound_flash[0].lLbound = 0;
  321.                     bound_flash[0].cElements = 0;
  322.  
  323.                     // write Flash URL link list to param array
  324.                     if ( NULL == (pSA_FLASH = SafeArrayCreate(VT_VARIANT, 1, bound_flash)) )
  325.                     {
  326.                         return;
  327.                     }
  328.  
  329.                     v[0].vt = VT_ARRAY | VT_BYREF | VT_VARIANT;
  330.                     v[0].pparray = &pSA_FLASH;
  331.  
  332.                     // write <URL, link title> pair list to param array
  333.                     if ( NULL == (pSA_URL = SafeArrayCreate(VT_VARIANT, 1, bound_url)) )
  334.                     {
  335.                         return;
  336.                     }
  337.                     long index[1];
  338.                     index[0] = 0;
  339.  
  340.                     VARIANT  varStr;
  341.  
  342.                     varStr.vt = VT_BSTR;
  343.  
  344.                     for (int i=0; i < linksCount; i++)
  345.                     {
  346.                         varStr.bstrVal = downloadInfo->links[i].url;
  347.                         hResult = SafeArrayPutElement(pSA_URL, index, &varStr);
  348.                         if (hResult != S_OK)
  349.                         {
  350.                             return;
  351.                         }
  352.                         index[0]++;
  353.  
  354.                         varStr.bstrVal = downloadInfo->links[i].comment;
  355.                         hResult = SafeArrayPutElement(pSA_URL, index, &varStr);
  356.                         if (hResult != S_OK)
  357.                         {
  358.                             return;
  359.                         }
  360.                         index[0]++;
  361.                     }
  362.  
  363.                     v[1].vt = VT_ARRAY | VT_BYREF | VT_VARIANT;
  364.                     v[1].pparray = &pSA_URL;
  365.  
  366.                     // write page title to param array
  367.                     BSTR page_title = SysAllocString(L"title");
  368.                     v[2].vt = VT_BSTR;
  369.                     v[2].bstrVal = page_title;
  370.  
  371.                     // write refer url to param array
  372.                     BSTR refer_url = SysAllocString(L"unknown");
  373.                     v[3].vt = VT_BSTR;
  374.                     v[3].bstrVal = refer_url;//downloadInfo->referer;
  375.  
  376.                     // write html content to param array
  377.                     BSTR html_content = SysAllocString(L"unkown");
  378.                     v[4].vt = VT_BSTR;
  379.                     v[4].bstrVal = html_content;
  380.  
  381.                     // invoke AddLinkList()
  382.                     h.invoke("AddLinkList", v, 5);
  383.  
  384.                     // cleanup
  385.                     SafeArrayDestroy(pSA_URL);
  386.                     SafeArrayDestroy(pSA_FLASH);
  387.                     SysFreeString(page_title);
  388.                     SysFreeString(refer_url);
  389.                     SysFreeString(html_content);
  390.                 }
  391.             }
  392.         }
  393. };
  394.  
  395.  
  396.  
  397. class DMSFreshDownload :
  398.     public DMSupportCOM
  399. {
  400.  
  401.  
  402. protected:
  403.     
  404.     const char * getProgId() { return "fdcatch.fdnscatcher"; }
  405.     
  406. public:
  407.     
  408.     const char * getName() { return "FreshDownload"; }
  409.  
  410.     void dispatch(const DownloadInfo *downloadInfo)
  411.     {
  412.         HELPER(h);
  413.         CookieManager cm(downloadInfo);
  414.         if(downloadInfo->opType==OP_ONE) 
  415.         {
  416.             LinkInfo l=downloadInfo->links[0];
  417.             VARIANT v[3];
  418.             v[2].vt=v[1].vt=VT_BSTR;
  419.             v[2].bstrVal=l.url; // URL
  420.             v[1].bstrVal=downloadInfo->referer; // referer
  421.             v[0].vt=VT_INT;
  422.             v[0].intVal=0; // quiet (0 means "show dialog")
  423.             h.invoke("AddURL",v,3);
  424.         } 
  425.         else
  426.         {
  427.             h.invoke("AddUrlList",FGArray(downloadInfo).asVariant(),1);
  428.         }
  429.     }
  430. };
  431.  
  432.  
  433. class DMSGetRight :
  434.     public DMSupport
  435. {
  436.  
  437. private:
  438.     static char *findGetRight(HKEY baseKey, char *leafPath, char *exeName) {
  439.         long res;
  440.         HKEY hk;
  441.         char *path=NULL;
  442.         
  443.  
  444.         if( (res=RegOpenKeyEx(baseKey,leafPath,0,KEY_QUERY_VALUE,&hk))==ERROR_SUCCESS)
  445.         {
  446.         
  447.         
  448.             char *installKey="InstallDir";
  449.             long pathLen=0;    
  450.             if((res=RegQueryValueEx(hk,installKey,0,NULL,NULL,(LPDWORD)&pathLen))==ERROR_SUCCESS) 
  451.             {
  452.                 BOOL lastAttempt;
  453.                 do {
  454.                     lastAttempt=exeName==NULL;
  455.                     if(lastAttempt) exeName="getright.exe";
  456.                     size_t fullLen = pathLen + strlen(exeName) + 2;
  457.                     path = new char[fullLen];
  458.                     BOOL fileExists=FALSE;
  459.                     if((res=RegQueryValueEx(hk,installKey,0,NULL,(LPBYTE)path,(LPDWORD)&pathLen))==ERROR_SUCCESS)
  460.                     {
  461.                         struct stat statbuf;
  462.                         if(sprintf_s(path, fullLen, "%s\\%s", path, exeName) > 0)
  463.                             fileExists = !stat(path, &statbuf);  
  464.                     }
  465.                     if(!fileExists) {
  466.                         delete path;
  467.                         path = NULL;
  468.                         if(!lastAttempt) exeName=NULL;
  469.                     }
  470.                 } while(! (path || lastAttempt) );
  471.             }
  472.             RegCloseKey(hk);    
  473.         }
  474.         
  475.         return path;
  476.         
  477.     }
  478.     
  479.     static char *findGetRight(char *exeName) 
  480.     {
  481.         char *path;
  482.         if(    ( path=findGetRight(HKEY_CURRENT_USER,"Software\\Headlight\\GetRight\\Config", exeName) )
  483.              || ( path=findGetRight(HKEY_LOCAL_MACHINE,"Software\\Headlight\\GetRight",exeName) ) )
  484.         {
  485.             return path;
  486.         }
  487.         throw "Can't find GetRight executable";
  488.     }
  489.  
  490.     static char *createCmdLine(char *path, char *opts, char *arg) {
  491.         size_t len = strlen(path)+strlen(opts)+strlen(arg)+6;
  492.         char *cmdLine=new char[len];
  493.         sprintf_s(cmdLine, len, "\"%s\" %s %s",path,opts,arg);
  494.         return cmdLine;
  495.     }
  496.  
  497. public:
  498.     
  499.     const char * getName() { return "GetRight"; }
  500.  
  501.     void check() 
  502.     {
  503.         delete findGetRight(NULL);
  504.     }
  505.     void dispatch(const DownloadInfo *downloadInfo) 
  506.     {
  507.         char *cmdLine=NULL;
  508.         char *path=NULL;
  509.         char *exeName;
  510.         char *arg;
  511.         char *tgargs=NULL;
  512.         if(downloadInfo->linksCount) {
  513.             exeName="togetright.exe";
  514.             if( strlen(downloadInfo->extras[2]) 
  515.                 && (strcmp("old",downloadInfo->extras[2])==0))
  516.             {
  517.                 arg = downloadInfo->links[0].url; // CHECK ME!!!
  518.             } else
  519.             {
  520.                 char *pattern = "/referer=%s /cookie=%s /url=%s";
  521.                 char *cookie = downloadInfo->links[0].cookie;
  522.                 char *referer = downloadInfo->referer;
  523.                 char *url = downloadInfo->links[0].url;
  524.                 
  525.                 size_t tgargsLen = strlen(referer)+
  526.                     strlen(cookie)+
  527.                     strlen(url)+
  528.                     strlen(pattern);
  529.                 arg = tgargs=new char[tgargsLen];
  530.  
  531.                 sprintf_s(tgargs, tgargsLen, pattern,    referer, cookie, url);
  532.             }
  533.         } else {
  534.             exeName=NULL;
  535.             arg=(char *)downloadInfo->referer;
  536.         }
  537.         /*
  538.         // GetRight doesn't work if not already started... needs more investigation
  539.  
  540.         if(!FindWindow(NULL, "GetRight "))
  541.         {
  542.             path = findGetRight(NULL);
  543.             if(createProcess(cmdLine = createCmdLine(path, "", ""), NULL))
  544.             {
  545.                 for(int j = 100; j-- > 0;) // 10 secs for GetRight to show up
  546.                 {
  547.                     if(FindWindow(NULL, "GetRight ")) break;
  548.                     sleep(100);
  549.                     if(j == 50) createProcess(cmdLine, NULL);
  550.                 }
  551.             }
  552.             if(cmdLine) delete[] cmdLine;
  553.         }
  554.         */
  555.         if(exeName || !path) path = findGetRight(exeName);
  556.         
  557.         BOOL ret=createProcess(cmdLine=createCmdLine(path = findGetRight(exeName),
  558.             downloadInfo->extras[0],
  559.             arg),NULL);
  560.         if(tgargs) delete [] tgargs;
  561.         // supplementary post-command
  562.         if( ret && (!exeName) && strlen(downloadInfo->extras[1])) 
  563.         {
  564.             if(cmdLine) delete[] cmdLine;
  565.             Sleep(500);
  566.             createProcess(cmdLine = createCmdLine(path,
  567.                 downloadInfo->extras[1],
  568.                 ""),NULL);
  569.         }
  570.         if(cmdLine) delete [] cmdLine;
  571.         if(path) delete [] path;
  572.         if(!ret) throw "Can't launch GetRight";
  573.     }
  574. };
  575.  
  576. class DMSHiDownload :
  577.     public DMSupportCOM
  578. {
  579.  
  580.  
  581. protected:
  582.     
  583.     const char * getProgId() { return "NetMoles.NetMoles"; }
  584.     
  585. public:
  586.     
  587.     const char * getName() { return "HiDownload"; }
  588.  
  589.     
  590.     void dispatch(const DownloadInfo *downloadInfo)
  591.     {
  592.         CookieManager cm(downloadInfo);
  593.         
  594.         
  595.         HELPER(h);
  596.         
  597.         
  598.         if(downloadInfo->linksCount == 1 && !FindWindow("HiDownload", NULL))
  599.         {
  600.             VARIANT v[2];
  601.             v[1].vt = v[0].vt = VT_BSTR;
  602.             LinkInfo l = downloadInfo->links[0];
  603.             v[1].bstrVal = l.url;
  604.             v[0].bstrVal = l.comment;
  605.             h.invoke("NMAddUrl", v, 2);
  606.         } else
  607.         {
  608.             FGArray fgArray(downloadInfo);
  609.             VARIANT v;
  610.             v.vt = VT_BYREF | VT_VARIANT;
  611.             v.pvarVal = fgArray.asVariant();
  612.             h.invoke("NMAddAllUrl", &v, 1);
  613.         }
  614.         
  615.     }
  616. };
  617.  
  618. class DMSInstantGet :
  619.     public DMSAddUrlFamily
  620. {
  621. protected:
  622.     const char * getProgId() { return "InstantGet.AddUrl"; }
  623. public:
  624.     const char * getName() { return "InstantGet"; }
  625. };
  626.  
  627.  
  628. #import "IDManTypeInfo.tlb" 
  629. #include "IDManTypeInfo.h"
  630. #include "IDManTypeInfo_i.c"  
  631.  
  632. class DMSInternetDownloadManager :
  633.     public DMSupportCOM
  634. {
  635.  
  636.  
  637. protected:
  638.     
  639.     const char * getProgId() { return "IDMGetAll.IDMAllLinksProcessor"; }
  640.     
  641. public:
  642.     
  643.     const char * getName() { return "Internet Download Manager"; }
  644.  
  645.     void check()
  646.     {
  647.         char *path = DMSupport::findProgram(HKEY_CLASSES_ROOT, 
  648.             "CLSID\\{AC746233-E9D3-49CD-862F-068F7B7CCCA4}\\LocalServer32");
  649.         if(!path) throw "Can't find Internet Download Manager executable";
  650.     }
  651.  
  652.     void dispatch(const DownloadInfo *downloadInfo)
  653.     {
  654.         long lc = downloadInfo->linksCount;
  655.         if(lc<1) return;
  656.  
  657.         LinkInfo *links=downloadInfo->links;
  658.         LinkInfo *l;
  659.  
  660.         ICIDMLinkTransmitter2* pIDM;
  661.         HRESULT hr = CoCreateInstance(CLSID_CIDMLinkTransmitter, NULL, CLSCTX_LOCAL_SERVER,
  662.                     IID_ICIDMLinkTransmitter2, (void**)&pIDM);
  663.         if (S_OK != hr) return;
  664.  
  665.         if(lc < 2)
  666.         {
  667.             VARIANT reserved;
  668.             reserved.vt=VT_EMPTY;
  669.             l = &links[0];
  670.             
  671.             pIDM->SendLinkToIDM2(l->url, downloadInfo->referer, l->cookie, l->postdata,
  672.                     NULL, NULL, NULL, NULL, 0,
  673.                     reserved, reserved);
  674.         } 
  675.         else 
  676.         {
  677.             
  678.             SAFEARRAY *pSA = NULL;
  679.             SAFEARRAYBOUND bound[2];
  680.             bound[0].lLbound = 0;
  681.             bound[0].cElements = lc;
  682.             bound[1].lLbound = 0;
  683.             bound[1].cElements = 4;
  684.             if ( pSA = SafeArrayCreate(VT_BSTR, 2, bound) )
  685.             {
  686.                 long index[2];
  687.                 CComBSTR url, cookie, comment;
  688.  
  689.                 for(long j = 0; j < lc; j++)
  690.                 {
  691.                     index[0] = j;
  692.                     l = &links[j];
  693.                     
  694.                     index[1] = 0;
  695.  
  696.                     url = (LPCOLESTR)l->url;
  697.                     cookie = (LPCOLESTR)l->cookie;
  698.                     comment = (LPCOLESTR)l->comment;
  699.  
  700.                     SafeArrayPutElement(pSA, index, url);
  701.             
  702.                     index[1] = 1;
  703.                     SafeArrayPutElement(pSA, index, cookie);
  704.             
  705.                     index[1] = 2;
  706.                     SafeArrayPutElement(pSA, index, comment);
  707.             
  708.                     index[1] = 3;
  709.                     SafeArrayPutElement(pSA, index, NULL);
  710.                 }
  711.                 VARIANT array;
  712.                 VariantInit(&array);
  713.                 array.vt = VT_ARRAY | VT_BSTR;
  714.                 array.parray = pSA;
  715.                 pIDM->SendLinksArray(downloadInfo->referer, &array);
  716.                 SafeArrayDestroy(pSA);
  717.             }
  718.         }
  719.         pIDM->Release();
  720.     }
  721. };
  722.  
  723.  
  724.  
  725. class DMSLeechGetBase :
  726.     public DMSupportCOM
  727. {
  728.  
  729. public:
  730.     
  731.     
  732.     void dispatch(const DownloadInfo *downloadInfo) 
  733.     {    
  734.         HELPER(h);
  735.         CookieManager cm(downloadInfo);
  736.         if(downloadInfo->linksCount>0) 
  737.         {
  738.             h.invoke(downloadInfo->opType==OP_ONE?"AddURL":"Wizard", downloadInfo->links[0].url);
  739.         } 
  740.         else 
  741.         {
  742.             h.invoke("Parse",downloadInfo->referer);
  743.         }
  744.     }
  745. };
  746.  
  747. class DMSLeechGet2002 :
  748.     public DMSLeechGetBase
  749. {
  750.     
  751. protected:
  752.     const char * getProgId() 
  753.     {
  754.         return "LeechGetIE.AddURL";
  755.     }
  756. public:
  757.     const char * getName() { return "LeechGet 2002"; }
  758. };
  759.  
  760. class DMSLeechGet :
  761.     public DMSLeechGetBase
  762. {
  763. protected:
  764.     const char * getProgId() 
  765.     {
  766.         return "LeechGetIE.LeechIE";
  767.     }
  768. public:
  769.     const char * getName() { return "LeechGet"; }
  770. };
  771.  
  772. class DMSMass_Downloader :
  773.     public DMSupportCOM
  774. {
  775.  
  776.  
  777. protected:
  778.     
  779.     const char * getProgId() { return "MassDown.AddUrl.1"; }
  780.     
  781. public:
  782.     
  783.     const char * getName() { return "Mass Downloader"; }
  784.  
  785.     void dispatch(const DownloadInfo *downloadInfo)
  786.     {
  787.         
  788.         
  789.         int linksCount=downloadInfo->linksCount;
  790.         if(linksCount<1) return;
  791.         {
  792.             VARIANT v[3];
  793.             v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  794.             HELPER(h);
  795.             CookieManager cg(downloadInfo);
  796.             DISPID di_AddUrlWithReferer;
  797.             h.getMemberID("AddUrlWithReferer",&di_AddUrlWithReferer);
  798.             
  799.             if(linksCount>1) {
  800.                 v[1].bstrVal=v[0].bstrVal=bstr_t("Begin.");
  801.                 h.invoke("AddUrl",v,2);
  802.             }
  803.             v[0].bstrVal=downloadInfo->referer;
  804.             LinkInfo *links=downloadInfo->links;
  805.             for(int j=0; j<linksCount; j++) {
  806.                 LinkInfo l=links[j];
  807.                 v[2].bstrVal=l.url;
  808.                 v[1].bstrVal=l.comment;
  809.                 h.invoke(&di_AddUrlWithReferer,v,3);
  810.             }
  811.             if(linksCount>1) {
  812.                 v[1].bstrVal=v[0].bstrVal=bstr_t("End.");
  813.                 h.invoke("AddUrl",v,2);
  814.             }
  815.         }
  816.     }
  817. };
  818.  
  819. class DMSNetAnts :
  820.     public DMSAddUrlFamily
  821. {
  822. protected:
  823.     const char * getProgId() { return "NetAnts.API"; }
  824. public:
  825.     const char * getName() { return "NetAnts"; }
  826. };
  827.  
  828.  
  829. class DMSNet_Transport :
  830.     public DMSupportCOM
  831. {
  832.  
  833. protected:
  834.     
  835.     const char * getProgId() { return "NTIEHelper.NTIEAddUrl"; }
  836.  
  837. public:
  838.     const char * getName() { return "Net Transport"; }
  839.  
  840.     void dispatch(const DownloadInfo *downloadInfo)
  841.     {
  842.         CookieManager cm(downloadInfo);
  843.         
  844.         int linksCount=downloadInfo->linksCount;
  845.         bstr_t *parms=downloadInfo->rawParms;
  846.         
  847.         SAFEARRAY *psaa[2]=
  848.         {
  849.             FGArray::createSafeArray(linksCount),
  850.             FGArray::createSafeArray(linksCount)
  851.         };
  852.  
  853.         VARIANT vstr;
  854.         vstr.vt = VT_BSTR;
  855.         long ix[]={0};
  856.         for(int j=1; ix[0]<linksCount; ix[0]++) 
  857.         {
  858.             for(int a=0; a<2; a++) 
  859.             {
  860.                 vstr.bstrVal=parms[j++];
  861.                 SafeArrayPutElement(psaa[a], ix, &vstr);
  862.             }
  863.             j+=2; // skipping cookie & postData;
  864.         }
  865.         
  866.         //AddList(referrer,urls, remarks);
  867.         VARIANT v[3];
  868.         v[2].vt=VT_BSTR;
  869.         v[2].bstrVal=downloadInfo->referer;
  870.         v[1].vt=v[0].vt=VT_VARIANT | VT_BYREF ;
  871.         SafeArrayAccessData(psaa[0], (void **)&(v[1].pvarVal));
  872.         SafeArrayAccessData(psaa[1], (void **)&(v[0].pparray));
  873.         HELPER(h);
  874.         h.invoke("AddList",v,3);
  875.  
  876.         SafeArrayUnlock(psaa[1]);
  877.         SafeArrayUnlock(psaa[0]);
  878.         SafeArrayDestroy(psaa[0]);
  879.         SafeArrayDestroy(psaa[1]);
  880.     }
  881. };
  882.  
  883.  
  884.  
  885. class DMSNet_Transport2 :
  886.     public DMSNet_Transport
  887. {
  888.  
  889. protected:
  890.     
  891.     const char * getProgId() { return "NXIEHelper.NXIEAddURL"; }
  892.  
  893. public:
  894.     const char * getName() { return "Net Transport 2"; }
  895.  
  896. };
  897.  
  898. class DMSWestByte :
  899.     public DMSupportCOM
  900. {
  901.  
  902. public:
  903.  
  904.  
  905.     void dispatch(const DownloadInfo *downloadInfo)
  906.     {
  907.         int linksCount=downloadInfo->linksCount;
  908.         bstr_t *parms=downloadInfo->rawParms;
  909.         
  910.         if(linksCount>0)
  911.         {
  912.             
  913.             VARIANT v[2];
  914.             v[0].vt = VT_BSTR ;
  915.             v[0].bstrVal=downloadInfo->referer; // referer
  916.             HELPER(h);
  917.             CookieManager cm(downloadInfo);
  918.             if(linksCount==1) 
  919.             {
  920.                 v[1].vt = VT_BSTR;
  921.                 v[1].bstrVal=downloadInfo->links[0].url;
  922.                 
  923.                 h.invoke("AddURL",v,2);
  924.             } 
  925.             else 
  926.             { 
  927.  
  928.                 FGArray fgArray(linksCount * 2);
  929.                 LinkInfo *links=downloadInfo->links;
  930.                 for (int j=0; j < linksCount; j++) {
  931.                     LinkInfo l=links[j];
  932.                     fgArray.addString(l.url);
  933.                     fgArray.addString(l.comment);
  934.                 }
  935.                 
  936.                 fgArray.asVariant(&v[1]);
  937.                 
  938.                 h.invoke("AddURLs",v,2);
  939.  
  940.             }
  941.         }
  942.     }
  943.     
  944. };
  945.  
  946.  
  947.  
  948. class DMSOrbit :
  949.     public DMSupportCOM
  950. {
  951. protected:
  952.     const char * getProgId() { return "Orbitmxt.Orbit"; }
  953.     
  954. public:
  955.     const char * getName() { return "Orbit"; }
  956.  
  957.     void dispatch(const DownloadInfo *downloadInfo)
  958.     {
  959.         CookieManager cm(downloadInfo);
  960.  
  961.         HELPER(h);
  962.         int linksCount=downloadInfo->linksCount;
  963.         if(linksCount>0)
  964.         {
  965.             if(linksCount<2)
  966.             {
  967.                 LinkInfo link=downloadInfo->links[0];
  968.                 VARIANT v[4];
  969.                 
  970.                 v[3].vt=v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  971.                 
  972.                 v[0].bstrVal=link.cookie;
  973.                 v[1].bstrVal=downloadInfo->referer;
  974.                 v[2].bstrVal=link.comment;
  975.                 v[3].bstrVal=link.url;
  976.  
  977.                 h.invoke("download",v,4);
  978.             }
  979.             else 
  980.             {
  981.                 VARIANT v[4];
  982.                 FGArray urlArray(linksCount);
  983.                 FGArray txtArray(linksCount);
  984.                 for(int i = 0; i < linksCount; i++) 
  985.                 {
  986.                     urlArray.addString( downloadInfo->links[i].url );
  987.                     txtArray.addString( downloadInfo->links[i].comment );
  988.                 }
  989.  
  990.                 urlArray.asVariant(&v[3]);
  991.                 txtArray.asVariant(&v[2]);
  992.                 v[1].vt=v[0].vt=VT_BSTR;
  993.                 v[1].bstrVal=downloadInfo->referer;
  994.                 v[0].bstrVal=downloadInfo->links[0].cookie;
  995.                 
  996.                 h.invoke("downloadList",v, 4);
  997.             }
  998.         }
  999.     }
  1000. };
  1001.  
  1002.  
  1003. class DMSwxDownloadFast :
  1004.     public DMSupport
  1005. {
  1006.  
  1007. private:
  1008.     
  1009.     
  1010.     static char *findProgram() 
  1011.     {
  1012.         char *path;
  1013.         char *leafPath = "Software\\wxWidgets Program\\wxDownload Fast";
  1014.         char *leafName = "ExePath";
  1015.         if(    (path = DMSupport::findProgram(HKEY_CURRENT_USER, leafPath, leafName)) ||
  1016.             (path = DMSupport::findProgram(HKEY_LOCAL_MACHINE, leafPath, leafName)) // Ma1 20061510
  1017.         ) return path;
  1018.         
  1019.         throw "Can't find wxDownload Fast executable";
  1020.     }
  1021.  
  1022.     static char *createCmdLine(char *path, char *arg) {
  1023.         size_t len = strlen(path)+strlen(arg)+8;
  1024.         char *cmdLine=new char[len];
  1025.         sprintf_s(cmdLine, len, "\"%s\" %s ", path, arg);
  1026.         return cmdLine;
  1027.     }
  1028.  
  1029. public:
  1030.     
  1031.     const char * getName() { return "wxDownload Fast"; }
  1032.  
  1033.     void check() 
  1034.     {
  1035.         delete findProgram();
  1036.     }
  1037.     void dispatch(const DownloadInfo *downloadInfo) 
  1038.     {
  1039.         char *cmdLine=NULL;
  1040.         char *path=NULL;
  1041.         char *arg;
  1042.         char *tgargs=NULL;
  1043.         BOOL ret = false;
  1044.         if(downloadInfo->linksCount)
  1045.         {
  1046.             char *referer=downloadInfo->referer;
  1047.  
  1048.             if (downloadInfo->linksCount == 1)
  1049.             {
  1050.                 char *pattern="--reference=%s \"%s\"";
  1051.                 char *url=downloadInfo->links[0].url;
  1052.                 size_t tgargsLen = strlen(referer)+
  1053.                     strlen(url)+
  1054.                     strlen(pattern);
  1055.                 arg = tgargs = new char[tgargsLen];
  1056.                 sprintf_s(tgargs, tgargsLen, pattern, referer, url);
  1057.             }
  1058.             else
  1059.             {
  1060.                 char *pattern="--reference=%s --list=\"%s\"";
  1061.                 FILE * fp; 
  1062.                 char tmppath[MAX_PATH];
  1063.                 if (GetTempPath(MAX_PATH, tmppath) == 0)
  1064.                 {
  1065.                     strcpy_s(tmppath, MAX_PATH, "c:");
  1066.                 }
  1067.                 strcat_s(tmppath, MAX_PATH, "TEMPURL.LST");
  1068.                 
  1069.                 if(fopen_s(&fp, tmppath, "w") != 0) 
  1070.                 { 
  1071.                     throw "FlashGot can't create file TEMPURL.LST for wxDownload Fast";
  1072.                 } 
  1073.                 for(int j=0,count=downloadInfo->linksCount; j<count; j++)
  1074.                 {
  1075.                     fputs(downloadInfo->links[j].url,fp);
  1076.                     fputc('\n',fp);
  1077.                 }
  1078.                 fclose(fp);
  1079.                 size_t tgargsLen = strlen(referer)+
  1080.                     strlen(tmppath)+
  1081.                     strlen(pattern);
  1082.                 arg=tgargs=new char[tgargsLen];
  1083.  
  1084.                 sprintf_s(tgargs, tgargsLen, pattern,referer,tmppath);
  1085.             }
  1086.             ret=createProcess(cmdLine=createCmdLine(path=findProgram(),
  1087.                 arg),NULL);
  1088.         }
  1089.  
  1090.         if(tgargs) delete [] tgargs;
  1091.         if(cmdLine)    delete [] cmdLine;
  1092.         if(path) delete [] path;
  1093.  
  1094.         if(!ret) throw "Can't launch wxDownload Fast";
  1095.     }
  1096. };
  1097.  
  1098.  
  1099. class DMSDownloadMaster :
  1100.     public DMSWestByte
  1101. {
  1102. protected:
  1103.     const char * getProgId() { return "DMIE.MoveURL"; }
  1104. public:
  1105.     const char * getName() { return "Download Master"; }
  1106. };
  1107.  
  1108. class DMSInternetDownloadAccelerator :
  1109.     public DMSWestByte
  1110. {
  1111. protected:
  1112.     const char * getProgId() { return "IDAIE.MoveURLIDA"; }
  1113. public:
  1114.     const char * getName() { return "Internet Download Accelerator"; }
  1115. };
  1116.  
  1117. class DMSReGet :
  1118.     public DMSupportCOM
  1119. {
  1120.     
  1121.     protected:
  1122.     const char * getProgId() 
  1123.     {
  1124.         return "ClickCatcher.DownloadAllFromContextMenu";
  1125.     }
  1126. public:
  1127.     const char * getName() { return "ReGet"; }
  1128.     
  1129.     void dispatch(const DownloadInfo *downloadInfo) 
  1130.     {    
  1131.         int linksCount=downloadInfo->linksCount;
  1132.         
  1133.         VARIANT v[5];
  1134.         v[0].vt=v[1].vt=v[2].vt=v[3].vt=v[4].vt=VT_BSTR;
  1135.         bstr_t referer=downloadInfo->referer; // referer
  1136.         
  1137.         FGCOMHelper *regetAll=NULL;
  1138.         DISPID di_AddDownload;
  1139.     
  1140.         if(linksCount>1) {
  1141.             regetAll=new FGCOMHelper(getProgId());
  1142.             regetAll->getMemberID("AddDownloadToList",&di_AddDownload);
  1143.         } else if(linksCount==1) {
  1144.             LinkInfo l=downloadInfo->links[0];
  1145.             if(strlen(l.postdata)) {
  1146.                 try 
  1147.                 {
  1148.                     FGCOMHelper dl("ReGetDx.RegetDownloadApi");
  1149.                     dl.set("Url",l.url);
  1150.                     dl.set("Referer",referer);
  1151.                     dl.set("Cookie",l.cookie);
  1152.                     dl.set("Info",l.comment);
  1153.                     dl.set("PostData",l.postdata);
  1154.                     dl.invoke("AddDownload");
  1155.                     return;
  1156.                 } catch(...) {}
  1157.             }
  1158.         }
  1159.         CookieManager cm(downloadInfo);
  1160.         LinkInfo *links=downloadInfo->links;
  1161.         for(int j=0; j<linksCount; j++) 
  1162.         {    
  1163.             LinkInfo l=links[j];
  1164.             
  1165.             for(int attempts=120; attempts-->0;) 
  1166.             { // we give ReGet 2mins to wake up
  1167.                 try 
  1168.                 {
  1169.                     FGCOMHelper dl("ClickCatcher.DownloadFromContextMenu");
  1170.                     
  1171.                     dl.set("Url",l.url);
  1172.                     dl.set("Referer",referer);
  1173.                     dl.set("Info",l.comment);
  1174.                     dl.set("Cookie",l.cookie); // -- it seems a dummy property, we use CookieManager which works
  1175.                     if(regetAll) {
  1176.                         VARIANT vdl;
  1177.                         vdl.vt=VT_DISPATCH;
  1178.                         vdl.pdispVal=dl.getIDispatch();
  1179.                         regetAll->invoke(&di_AddDownload,&vdl,1);
  1180.                     } else {
  1181.                         dl.invoke("AddDownload");
  1182.                     }
  1183.  
  1184.                     break;
  1185.                 } 
  1186.                 catch(_com_error ce)
  1187.                 {
  1188.                     Sleep(1000);
  1189.                     if(attempts==0) throw "ReGet timeout";
  1190.                 }
  1191.             }
  1192.         }
  1193.  
  1194.         if(regetAll) try 
  1195.         { 
  1196.             regetAll->invoke("UrlList",NULL,0);
  1197.             delete regetAll;
  1198.         } catch(...) {}
  1199.     }
  1200. };
  1201.  
  1202.  
  1203. class DMSStarDownloader :
  1204.     public DMSupportCOM
  1205. {
  1206.  
  1207.  
  1208. protected:
  1209.     
  1210.     const char * getProgId() { return "SDExt.StarDownExt"; }
  1211.     
  1212. public:
  1213.     
  1214.     const char * getName() { return "Star Downloader"; }
  1215.  
  1216.     void dispatch(const DownloadInfo *downloadInfo)
  1217.     {
  1218.         
  1219.         HELPER(downloader);
  1220.         DISPID di_DownloadURL;
  1221.         downloader.getMemberID("DownloadURL",&di_DownloadURL);
  1222.         
  1223.         VARIANT v[2];
  1224.         v[0].vt = v[1].vt = VT_BSTR;
  1225.         v[0].bstrVal = downloadInfo->referer; // referrer
  1226.         LinkInfo *links=downloadInfo->links;
  1227.         for (long j=0, len=downloadInfo->linksCount; j < len ; j++) { 
  1228.             v[1].bstrVal=links[j].url;
  1229.             downloader.invoke(&di_DownloadURL,v,2);
  1230.         }
  1231.     }
  1232. };
  1233.  
  1234. class DMSThunder :
  1235.     public DMSupportCOM
  1236. {
  1237.  
  1238.  
  1239. protected:
  1240.  
  1241.     const char * getProgId() { return "ThunderAgent.Agent"; }
  1242.     
  1243. public:
  1244.     
  1245.     const char * getName() { return "Thunder"; }
  1246.  
  1247.     void dispatch(const DownloadInfo *downloadInfo)
  1248.     {
  1249.         CookieManager cm(downloadInfo);
  1250.         HELPER(h);
  1251.         VARIANT v[8];
  1252.         v[7].vt = v[6].vt = v[5].vt = v[4].vt = v[3].vt = VT_BSTR;
  1253.         v[2].vt = v[1].vt = v[0].vt = VT_INT;
  1254.  
  1255.         LinkInfo *links=downloadInfo->links;
  1256.         for (long j=0, len=downloadInfo->linksCount; j<len ; j++) 
  1257.         { 
  1258.             v[7].bstrVal=links[j].url;
  1259.             v[6].bstrVal=_bstr_t("");
  1260.             v[5].bstrVal=_bstr_t("");
  1261.             v[4].bstrVal=links[j].comment;
  1262.             v[3].bstrVal=downloadInfo->referer;
  1263.             v[2].intVal=-1;
  1264.             v[1].intVal=0;
  1265.             v[0].intVal=-1;
  1266.             h.invoke("AddTask",v,8);
  1267.         }
  1268.  
  1269.         h.invoke("CommitTasks");
  1270.     }
  1271. };
  1272.  
  1273. class DMSGigaGet : 
  1274.     public DMSupportCOM
  1275. {
  1276.     
  1277. protected:
  1278.     const char * getProgId() { return "GigaGetBho.CatchRightClick.1"; }
  1279.     
  1280. public:
  1281.     const char * getName() { return "GigaGet"; }
  1282.  
  1283.     void dispatch(const DownloadInfo *downloadInfo)
  1284.     {
  1285.         CookieManager cm(downloadInfo);
  1286.         HELPER(h);
  1287.         VARIANT v[2];
  1288.         v[0].vt= VT_BYREF;
  1289.  
  1290.         FGArray fgArray(downloadInfo);
  1291.         v[1].vt=VT_BYREF | VT_VARIANT;
  1292.         v[1].pvarVal=fgArray.asVariant();
  1293.         h.get("AddAllUrl",v,1);
  1294.     }
  1295. };
  1296.  
  1297. class DMSThunderOld :
  1298.     public DMSGigaGet
  1299. {
  1300.  
  1301.  
  1302. protected:
  1303.  
  1304.     const char * getProgId() { return "Xunleibho.CatchRightClick.1"; }
  1305.     
  1306. public:
  1307.     
  1308.     const char * getName() { return "Thunder (Old)"; }
  1309.  
  1310. };
  1311.  
  1312.  
  1313. class DMSTrueDownloader :
  1314.     public DMSupportCOM
  1315. {
  1316.  
  1317.  
  1318. protected:
  1319.     const char * getProgId() { return "TrueDownloaderProject.TrueDownloader"; }
  1320.     
  1321. public:
  1322.     const char * getName() { return "TrueDownloader"; }
  1323.  
  1324.     void dispatch(const DownloadInfo *downloadInfo)
  1325.     {
  1326.         
  1327.         HELPER(downloader);
  1328.         DISPID di_MenuURL;
  1329.         downloader.getMemberID("MenuURL",&di_MenuURL);
  1330.         
  1331.         VARIANT v[3];
  1332.         v[0].vt = v[1].vt = v[2].vt = VT_BSTR;
  1333.         v[1].bstrVal = downloadInfo->referer; // referrer
  1334.         LinkInfo *links=downloadInfo->links;
  1335.         for (long j=0, len=downloadInfo->linksCount; j < len ; j++) 
  1336.         { 
  1337.             v[2].bstrVal=links[j].url;
  1338.             v[0].bstrVal=links[j].cookie;
  1339.             downloader.invoke(&di_MenuURL,v,3);
  1340.         }
  1341.     }
  1342. };
  1343.  
  1344. class DMSWellGet :
  1345.     public DMSupport
  1346. {
  1347.     
  1348.     const char * getProgId() { return "NxApi.myComponent"; }
  1349.     
  1350. public:
  1351.     
  1352.     const char * getName() { return "WellGet"; }
  1353.     
  1354.     void check() {
  1355.         dispatch(NULL);
  1356.     }
  1357.  
  1358.     void dispatch(const DownloadInfo *downloadInfo)
  1359.     {
  1360.         
  1361.     
  1362.         HKEY hk = NULL;
  1363.         BOOL ok = false;
  1364.         char app_path[MAX_PATH];
  1365.         if(downloadInfo && strlen((char *)(downloadInfo->extras[2]))) 
  1366.         { // explicit path
  1367.             strcpy_s(app_path, MAX_PATH, (char *)downloadInfo->extras[2]);
  1368.         } else if(RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\WellGet"),0,KEY_QUERY_VALUE,&hk)==ERROR_SUCCESS)
  1369.         {    
  1370.             DWORD dwDisposition = 1023;
  1371.             BYTE szpath[1024];
  1372.             DWORD type_1=REG_SZ ; 
  1373.             if(RegQueryValueEx(hk, NULL, NULL,&type_1, szpath, &dwDisposition)==ERROR_SUCCESS)
  1374.             {    
  1375.                 sprintf_s(app_path, MAX_PATH, "%s\\WellGet.exe", szpath);
  1376.             }
  1377.             RegCloseKey(hk);
  1378.         }
  1379.         
  1380.         // check WellGet path
  1381.         struct stat statbuf;
  1382.         if(stat(app_path,&statbuf))  throw "Can't find WellGet executable";
  1383.         
  1384.         if(downloadInfo && downloadInfo->linksCount > 0)
  1385.         {
  1386.             CookieManager cm(downloadInfo);
  1387.             char cmdLine[32767];
  1388.  
  1389.             if(downloadInfo->opType==OP_ONE) 
  1390.             {
  1391.                 try // try COM first, to overcome command line bug in latest (1.25 - 0118) build
  1392.                 {
  1393.                     HELPER(h);
  1394.     
  1395.                     LinkInfo l=downloadInfo->links[0];
  1396.                     VARIANT v[3];
  1397.                     v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  1398.                     v[2].bstrVal=l.url; // URL
  1399.                     v[1].bstrVal=l.comment;
  1400.                     v[0].bstrVal=downloadInfo->referer; // referer
  1401.                     h.invoke("AddURL", v, 3);
  1402.                     return;
  1403.                 } catch(...)
  1404.                 { // fall back to command line
  1405.                     LinkInfo l=downloadInfo->links[0];
  1406.                     
  1407.                     sprintf_s(cmdLine, sizeof(cmdLine), "%s wget -r:\"%s\" -c:\"%s\" \"%s\"",
  1408.                         app_path,
  1409.                         (char *)downloadInfo->referer,
  1410.                         (char *)l.comment, (char *)l.url);
  1411.                 } 
  1412.             }
  1413.             else 
  1414.             {
  1415.                 LinkInfo *links=downloadInfo->links;
  1416.                 
  1417.                 FILE * fp; 
  1418.                 char path[MAX_PATH];
  1419.                 if (GetTempPath(MAX_PATH, path)==0)
  1420.                 {
  1421.                     strcpy_s(path, MAX_PATH, "c:");
  1422.                 }
  1423.                 strcat_s(path, MAX_PATH, "TEMPURL.TXT");
  1424.  
  1425.                 if(fopen_s(&fp, path, "w") != 0) 
  1426.                 { 
  1427.                     throw "FlasGot can't create file TEMPURL.TXT for WellGet";
  1428.                 } 
  1429.                 fputs(downloadInfo->referer,fp);
  1430.                 fputc('\n',fp);
  1431.                 for(int j=0,count=downloadInfo->linksCount; j<count; j++) {
  1432.                     LinkInfo l=links[j];
  1433.                     fputs(l.url,fp);
  1434.                     fputc('\n',fp);
  1435.                     fputs(l.comment,fp);
  1436.                     fputc('\n',fp);
  1437.                 }
  1438.                 fclose(fp);
  1439.                 sprintf_s(cmdLine, sizeof(cmdLine), "%s -u addlist", app_path);
  1440.             }
  1441.  
  1442.             createProcess(cmdLine, NULL);
  1443.         }
  1444.  
  1445.     }
  1446.         
  1447.     
  1448.     
  1449. };
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455. // [END DOWNLOAD MANAGER SUPPORT CLASSES]
  1456.  
  1457.  
  1458. typedef struct _DMSNode {
  1459.     unsigned int id;
  1460.     DMSupport *dms;
  1461.     _DMSNode *prev;
  1462. } DMSNode;
  1463.  
  1464.  
  1465.  
  1466. class DMSFactory 
  1467. {
  1468. private:
  1469.     static DMSFactory *instance;
  1470.     DMSNode *last;
  1471.     DMSupport *add(DMSupport *dms) {
  1472.         if(!last) {
  1473.             (last=new DMSNode())->prev=NULL;
  1474.             last->id=1;
  1475.         } else {
  1476.             DMSNode *newNode=new DMSNode();
  1477.             newNode->prev=last;
  1478.             newNode->id=last->id << 1;
  1479.             last=newNode;
  1480.         }
  1481.         return last->dms=dms;
  1482.     }
  1483.  
  1484.     DMSFactory() : last(NULL) {
  1485.  
  1486.  
  1487.         add(new DMSBitComet());
  1488.         add(new DMSDownloadAcceleratorPlus());
  1489.         add(new DMSDownloadMaster());
  1490.         add(new DMSFlashGet());
  1491.         add(new DMSFlashGet2());
  1492.         add(new DMSFlashGet2X());
  1493.         add(new DMSFreeDownloadManager());
  1494.         add(new DMSFreshDownload());
  1495.         add(new DMSGetRight());
  1496.         add(new DMSGigaGet());
  1497.         add(new DMSHiDownload());
  1498.         add(new DMSInstantGet());
  1499.         add(new DMSInternetDownloadAccelerator());
  1500.         add(new DMSInternetDownloadManager());
  1501.         add(new DMSLeechGet2002());
  1502.         add(new DMSLeechGet());
  1503.         add(new DMSMass_Downloader());
  1504.         add(new DMSNetAnts());
  1505.         add(new DMSNet_Transport());
  1506.         add(new DMSNet_Transport2());
  1507.         add(new DMSOrbit());
  1508.         add(new DMSReGet());
  1509.         add(new DMSStarDownloader());
  1510.         add(new DMSTrueDownloader());
  1511.         add(new DMSThunder());
  1512.         add(new DMSThunderOld());
  1513.         add(new DMSWellGet());
  1514.         add(new DMSwxDownloadFast());
  1515.  
  1516. }
  1517.  
  1518. public:
  1519.     
  1520.     static DMSFactory *getInstance() {
  1521.         return instance?instance:instance=new DMSFactory();        
  1522.     }
  1523.     
  1524.     
  1525.     DMSupport *getDMS(char *name) {
  1526.         DMSNode *cursor=last;
  1527.         for(; cursor && strcmp(cursor->dms->getName(),name); cursor=cursor->prev);
  1528.         return cursor 
  1529.             ?cursor->dms
  1530.             :NULL;    
  1531.     }
  1532.     
  1533.     unsigned int checkAll() {
  1534.         unsigned int retVal=0;
  1535.         fprintf(stdout,"FlashGot Win Bridge %s\r\n",VERSION);
  1536.         FGCOMGuard::addClient();
  1537.         for(DMSNode *cursor=last; cursor; cursor=cursor->prev) {
  1538.             try {
  1539.                 fprintf(stdout,"%s|",cursor->dms->getName());
  1540.                 cursor->dms->check();
  1541.                 fprintf(stdout,"OK\n");
  1542.                 continue;
  1543.             } catch(_com_error ce) {
  1544.                 fprintf(stdout,"BAD\nCOM error: %s\n", ce.ErrorMessage());
  1545.             } catch(...) {
  1546.                 fprintf(stdout,"BAD\nunexpected unknown error!\n");
  1547.             }
  1548.             retVal |= cursor->id;
  1549.         }
  1550.         FGCOMGuard::removeClient();
  1551.         return retVal;
  1552.     }
  1553.  
  1554.  
  1555.  
  1556.     ~DMSFactory() {
  1557.         DMSNode *cursor=last;
  1558.         while( cursor ) {
  1559.             delete cursor->dms;
  1560.             last=cursor;
  1561.             cursor=last->prev;
  1562.             delete last;
  1563.         }
  1564.     }
  1565. };
  1566. DMSFactory * DMSFactory::instance=NULL;
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576. DMSupport* createDMS(char *name) {
  1577.     DMSupport *res=DMSFactory::getInstance()->getDMS(name);
  1578.     if(res) return res;
  1579.     sprintf_s(g_buf, BUF_SIZE, "Unsupported Download Manager %s", name);
  1580.     fail(g_buf, -8000);
  1581.     return NULL;
  1582. }
  1583.  
  1584. wchar_t *UTF8toUnicode(const char *src) {
  1585.     return src && (
  1586.         MultiByteToWideChar(CP_UTF8,0,src,-1,  g_wbuf, BUF_SIZE) 
  1587.         || MultiByteToWideChar(CP_ACP,0,src,-1,g_wbuf, BUF_SIZE)
  1588.         )
  1589.         ? g_wbuf : L""
  1590.         ;
  1591. }
  1592.  
  1593. bstr_t * readLine(FILE *stream, bstr_t *buffer) 
  1594. {
  1595.     
  1596.     bool isLine=false;
  1597.     for(char *res; res=fgets(g_buf,BUF_SIZE,stream); )
  1598.     {
  1599.         size_t lastPos=strlen(res)-1;
  1600.         while(lastPos>=0 && 
  1601.             (res[lastPos]==0x0a || res[lastPos]==0x0d)
  1602.             )
  1603.         {
  1604.             res[lastPos--]='\0';
  1605.             isLine=true;
  1606.         }
  1607.         
  1608.         buffer->Assign(*buffer + UTF8toUnicode((const char*) res));
  1609.         if(isLine) break;
  1610.     }
  1611.     return buffer;
  1612. }
  1613.  
  1614.  
  1615.  
  1616. int performTest(char *outfname)
  1617. {
  1618.     if(outfname) 
  1619.     {
  1620.         FILE *fp;
  1621.         freopen_s(&fp, outfname, "w", stdout);
  1622.         freopen_s(&fp, outfname,"a", stderr);
  1623.     }
  1624.     DMSFactory::getInstance()->checkAll();
  1625.     exit(0);
  1626. }
  1627.  
  1628.  
  1629. void parseHeader(DownloadInfo *downloadInfo, char *header_buf)
  1630. {
  1631. #define HEADER_COUNT 4
  1632.     char *header[HEADER_COUNT];
  1633.     char *cur=header_buf;
  1634.     for(int j=0; j<HEADER_COUNT ; ) 
  1635.     {
  1636.         if( (header[j++]=cur)  && (cur=strchr(cur,';')) ) 
  1637.         {
  1638.             cur[0]='\0';
  1639.             ++cur;
  1640.         } 
  1641.         else
  1642.         {
  1643.             if(j!=HEADER_COUNT) fail("Malformed header",17);    
  1644.             break;
  1645.         }
  1646.     }
  1647.  
  1648.     downloadInfo->linksCount=atoi(header[0]);
  1649.     downloadInfo->dmName=header[1];
  1650.     int typeId=atoi(header[2]);
  1651.     downloadInfo->opType = (typeId<OP_MIN||typeId>OP_MAX)
  1652.         ?OP_ALL:(OpType)typeId;
  1653.     downloadInfo->folder = bstr_t(UTF8toUnicode((const char *)header[3]));
  1654. }
  1655.  
  1656. void processJobFile(FILE *f)
  1657. {
  1658.     DMSupport *dms = NULL;
  1659.     const char *errMsg="Download manager not properly installed.\n%s";
  1660.     BOOL completed=FALSE;
  1661.     try 
  1662.     {
  1663.         DownloadInfo downloadInfo;
  1664.  
  1665.         char header_buf[BUF_SIZE];
  1666.         if(fgets(header_buf, BUF_SIZE, f))
  1667.         {
  1668.             parseHeader(&downloadInfo, header_buf);
  1669.             int linksCount=downloadInfo.linksCount;
  1670.             int parmsCount = 1 + linksCount * 4 + EXTRAS_COUNT; // referer + (url + info + cookie + postdata) * 4 + referer cookie + referer referer :-)
  1671.  
  1672.             bstr_t *parms=downloadInfo.rawParms=new bstr_t[parmsCount];
  1673.             
  1674.             LinkInfo *links=downloadInfo.links=new LinkInfo[linksCount];
  1675.             
  1676.             for(int j=0; j<parmsCount; j++) {
  1677.                 parms[j]="";
  1678.                 bstr_t *buffer = &parms[j];
  1679.                 readLine(f, buffer);
  1680.             }
  1681.             
  1682.             downloadInfo.referer = parms[0];
  1683.             downloadInfo.links = (LinkInfo *) &parms[1];
  1684.             downloadInfo.extras = &parms[parmsCount - EXTRAS_COUNT];
  1685.  
  1686.             (dms=createDMS(downloadInfo.dmName))->dispatch(&downloadInfo);
  1687.             printf("%s",downloadInfo.folder);
  1688.         }
  1689.         completed=TRUE;
  1690.     } 
  1691.     catch(_com_error ce)
  1692.     {
  1693.         sprintf_s(g_buf, BUF_SIZE, errMsg,ce.ErrorMessage());
  1694.     }
  1695.     catch(char *ex) {
  1696.         sprintf_s(g_buf, BUF_SIZE, errMsg, ex);
  1697.     } 
  1698.     //catch(...) {
  1699.     //    sprintf(g_buf,errMsg,"");
  1700.     //}
  1701.     
  1702.     if(dms) delete dms;
  1703.     
  1704.     if(!completed) fail(g_buf,0x02000);
  1705. }
  1706.  
  1707. int performDownload(char *fname)
  1708. {
  1709.     FILE *f;
  1710.     size_t doneLen = strlen(fname) + 6;
  1711.     char *done = new char[doneLen];
  1712.     
  1713.     sprintf_s(done, doneLen, "%s.done", fname);    
  1714.     if(fopen_s(&f, fname, "rb") != 0)  
  1715.     {
  1716.         struct stat statbuf;
  1717.         if(stat(done, &statbuf)) // done file doesn't exist  
  1718.         {
  1719.             sprintf_s(g_buf, BUF_SIZE, "Can't open file %s", fname);
  1720.             fail(g_buf, 0x01000);
  1721.         } else {
  1722.             remove(done);
  1723.         }
  1724.     }
  1725.     else
  1726.     {    
  1727.         if(!feof(f))    
  1728.         {
  1729.             processJobFile(f);
  1730.         }
  1731.         else 
  1732.         {
  1733.             sprintf_s(g_buf, BUF_SIZE, "Temporary file %s is empty", fname);
  1734.             fail(g_buf,0x03000);
  1735.         }
  1736.         fclose(f);
  1737.         
  1738.         if(!strstr(done,"test"))
  1739.         {
  1740.             remove(done);
  1741.             rename(fname,done);
  1742.         }
  1743.     }
  1744.     delete [] done;
  1745.     return 0;
  1746. }
  1747.  
  1748. int main(int argc, char* argv[])
  1749. {
  1750.     return (argc<2 || strcmp(argv[1],"-o") == 0 )
  1751.         ?performTest(argc>2?argv[2]:NULL)
  1752.         :performDownload(argv[1]);
  1753. }
  1754.  
  1755. int WINAPI
  1756. WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
  1757. {
  1758.     return main(__argc, __argv); 
  1759. }
  1760.